package com.tx.core.mybatis.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.override.MybatisMapperProxy;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
import com.baomidou.mybatisplus.core.toolkit.reflect.GenericTypeUtils;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.tx.core.exceptions.SILException;
import com.tx.core.exceptions.util.AssertUtils;
import com.tx.core.mybatis.conditions.QuerierWrapper;
import com.tx.core.mybatis.conditions.UpdaterWrapper;
import com.tx.core.mybatis.mapper.MybatisBaseMapper;
import com.tx.core.mybatis.service.IBaseService;
import com.tx.core.paged.model.PagedList;
import com.tx.core.util.TableInfoUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;

/**
 * <pre>
 * 功能简述: MybatisBaseService
 * </pre>
 *
 * @author PengQingyang
 * 创建时间 [2024/4/2]
 */
public class MybatisPlusBaseService<T, ID extends Serializable, M extends MybatisBaseMapper<T, ID>>
        implements IBaseService<T, ID> {

    protected final Logger logger = LoggerFactory.getLogger(IBaseService.class);

    protected final Log log = LogFactory.getLog(getClass());

    private final ConversionService conversionService = DefaultConversionService.getSharedInstance();

    protected final Class<?>[] typeArguments = GenericTypeUtils.resolveTypeArguments(getClass(),
            MybatisPlusBaseService.class);

    protected final Class<T> entityClass = currentModelClass();

    protected final Class<M> mapperClass = currentMapperClass();

    private volatile SqlSessionFactory sqlSessionFactory;

    @Autowired
    protected M baseMapper;

    /**
     * 获取实体类型
     *
     * @return
     */
    @Override
    public T newEntityInstance() {
        try {
            T entity = getEntityClass().getDeclaredConstructor().newInstance();
            return entity;
        } catch (InvocationTargetException | InstantiationException | IllegalAccessException |
                 NoSuchMethodException e) {
            throw new SILException("根据类型创建对象实例", e);
        }
    }

    @Override
    public void save(T data) {
        AssertUtils.notNull(data, "entity is null.");

        this.baseMapper.save(data);
    }

    /**
     * 保存对象实例
     *
     * @param entity                 需要保存的数据实体。
     * @param updateWrapperGenerator 一个函数，接受一个数据实体，返回一个对该实体进行更新操作的包装器。这个包装器用于
     *                               包装更新操作的逻辑。
     */
    @Override
    public void save(T entity, Function<T, Wrapper<T>> updateWrapperGenerator) {
        AssertUtils.notNull(entity, "entity is null.");
        AssertUtils.notNull(updateWrapperGenerator, "updateWrapperGenerator is null.");

        BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(entity);
        String pkPropertyName = TableInfoUtils.parsePKTableColumn(getEntityClass()).getPropertyName();

        ID pk = (ID) bw.getPropertyValue(pkPropertyName);
        if (ObjectUtil.isEmpty(pk)) {
            this.baseMapper.insert(entity);
        } else {
            T res = this.baseMapper.findById(pk);
            if (res != null) {
                this.baseMapper.update(entity, updateWrapperGenerator.apply(entity));
            }
        }
    }

    /**
     * 批量保存对象实例
     *
     * @param entityList       需要保存的数据实体列表。
     * @param batchSize        批量保存的批次大小。
     * @param useBatchExecutor 是否使用批量执行器。
     */
    @Override
    public void batchSave(List<T> entityList, int batchSize, boolean useBatchExecutor) {
        if (CollectionUtils.isEmpty(entityList)) {
            return;
        }
        if (useBatchExecutor) {
            String insertStatement = getSqlStatement(SqlMethod.INSERT_ONE);
            String updateStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);
            String pkPropertyName = TableInfoUtils.parsePKTableColumn(getEntityClass()).getPropertyName();
            executeBatch(entityList, batchSize, (sqlSession, entity) -> {
                BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(entity);
                ID pkValue = (ID) bw.getPropertyValue(pkPropertyName);
                if (ObjectUtil.isEmpty(pkValue)) {
                    sqlSession.insert(insertStatement, entity);
                } else {
                    if (CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID),
                            entity))) {
                        sqlSession.insert(insertStatement, entity);
                    } else {
                        MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
                        param.put(Constants.ENTITY, entity);
                        sqlSession.update(updateStatement, param);
                    }
                }
            });
        } else {
            entityList.stream().forEach(entity -> {
                save(entity);
            });
        }
    }

    /**
     * 批量保存对象实例
     *
     * @param entityList             需要保存的数据实体列表。
     * @param updateWrapperGenerator 一个函数，接受一个数据实体，返回一个对该实体进行更新操作的包装器。这个包装器用于
     *                               包装更新操作的逻辑。
     * @param batchSize              批量保存的批次大小。
     * @param useBatchExecutor       是否使用批量执行器。
     */
    @Override
    public void batchSave(List<T> entityList, Function<T, Wrapper<T>> updateWrapperGenerator,
                          int batchSize, boolean useBatchExecutor) {
        if (CollectionUtils.isEmpty(entityList)) {
            return;
        }
        if (useBatchExecutor) {
            String insertStatement = getSqlStatement(SqlMethod.INSERT_ONE);
            String updateStatement = getSqlStatement(SqlMethod.UPDATE);
            String pkPropertyName = TableInfoUtils.parsePKTableColumn(getEntityClass()).getPropertyName();
            executeBatch(entityList, batchSize, (sqlSession, entity) -> {
                BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(entity);
                ID pkValue = (ID) bw.getPropertyValue(pkPropertyName);
                if (ObjectUtil.isEmpty(pkValue)) {
                    sqlSession.insert(insertStatement, entity);
                } else {
                    if (CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID),
                            entity))) {
                        sqlSession.insert(insertStatement, entity);
                    } else {
                        Map<String, Object> param = new HashMap<>();
                        param.put(Constants.WRAPPER, updateWrapperGenerator.apply(entity));
                        sqlSession.update(updateStatement, param);
                    }
                }
            });
        } else {
            entityList.stream().forEach(entity -> {
                save(entity);
            });
        }
    }

    /**
     * 插入对象实例
     *
     * @param data 要插入的数据实体，类型为泛型 T
     */
    @Override
    public void insert(T data) {
        AssertUtils.notNull(data, "entity is null.");

        this.baseMapper.insert(data);
    }

    /**
     * 批量插入对象实例
     *
     * @param entityList       要插入的数据列表，不应为空。
     * @param batchSize        批量插入的大小，即每次提交到数据库的记录数。正值表示批量大小。
     * @param useBatchExecutor 指定是否使用批量执行器来执行插入操作。当为true时，将尝试使用更高效的批量执行策略。
     */
    @Override
    public void batchInsert(List<T> entityList, int batchSize, boolean useBatchExecutor) {
        if (CollectionUtils.isEmpty(entityList)) {
            return;
        }
        if (useBatchExecutor) {
            String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
            executeBatch(entityList, batchSize, (sqlSession, entity) -> {
                sqlSession.insert(sqlStatement, entity);
            });
        } else {
            entityList.stream().forEach(entity -> {
                insert(entity);
            });
        }
    }

    /**
     * 更新对象实例
     *
     * @param pk 要更新的数据实体，类型为泛型 T
     */
    @Override
    public boolean deleteById(ID pk) {
        return this.baseMapper.deleteById(pk) > 0;
    }

    /**
     * 更新对象实例
     *
     * @param entity 要更新的数据实体，类型为泛型 T
     */
    @Override
    public int delete(T entity) {
        return this.baseMapper.deleteById(entity);
    }

    /**
     * 批量更新对象实例
     *
     * @param entityList       要更新的数据实体列表。
     * @param batchSize        批量更新的批次大小。
     * @param useBatchExecutor 是否使用批量执行器。
     */
    @Override
    public void batchDelete(List<T> entityList, int batchSize, boolean useBatchExecutor) {
        if (CollectionUtils.isEmpty(entityList)) {
            return;
        }
        if (useBatchExecutor) {
            String sqlStatement = getSqlStatement(SqlMethod.DELETE_BY_ID);
            executeBatch(entityList, batchSize, (sqlSession, entity) -> {
                sqlSession.delete(sqlStatement, entity);
            });
        } else {
            entityList.stream().forEach(entity -> {
                delete(entity);
            });
        }
    }

    /**
     * 更新对象实例
     *
     * @param id     要更新的数据实体，类型为泛型 T
     * @param entity 要更新的数据实体，类型为泛型 T
     */
    @Override
    public boolean updateById(ID id, T entity) {
        AssertUtils.notEmpty(id, "id is null.");
        AssertUtils.notNull(entity, "entity is null.");

        BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(entity);
        bw.setPropertyValue(TableInfoUtils.parsePKTableColumn(getEntityClass()).getPropertyName(), id);

        int count = this.baseMapper.updateById(entity);
        if (count < 1) {
            return false;
        }
        AssertUtils.isTrue(count == 1,
                "update count should == 1.but actual is :{}",
                new Object[]{count});
        return true;
    }

    /**
     * 更新对象实例
     *
     * @param entity 要更新的数据实体，类型为泛型 T
     */
    @Override
    public int update(T entity) {
        AssertUtils.notNull(entity, "entity is null.");

        return this.baseMapper.updateById(entity);
    }

    /**
     * 更新对象实例
     *
     * @param id      要更新的数据实体，类型为泛型 T
     * @param entity  要更新的数据实体，类型为泛型 T
     * @param wrapper 一个函数，接受一个数据实体，返回一个对该实体进行更新操作的包装器。这个包装器用于
     *                包装更新操作的逻辑。
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
    public boolean updateById(ID id, T entity, Wrapper<T> wrapper) {
        AssertUtils.notEmpty(id, "id is null.");
        AssertUtils.notTrue(entity == null && wrapper == null, "entity and wrapper is null.");

        ((AbstractWrapper)wrapper).eq(TableInfoUtils.parsePKTableColumn(getEntityClass()).getColumnName(), id);
        int count = this.baseMapper.update(entity, wrapper);
        if (count < 1) {
            return false;
        }
        AssertUtils.isTrue(count == 1,
                "update count should == 1.but actual is :{}",
                new Object[]{count});
        return true;
    }

    /**
     * 更新对象实例
     *
     * @param entity  要更新的数据实体，类型为泛型 T
     * @param wrapper 一个函数，接受一个数据实体，返回一个对该实体进行更新操作的包装器。这个包装器用于
     *                包装更新操作的逻辑。
     */
    @Override
    public int update(T entity, Wrapper<T> wrapper) {
        AssertUtils.notTrue(entity == null && wrapper == null, "entity and wrapper is null.");

        int count = 0;
        if (wrapper != null) {
            count = this.baseMapper.update(entity, wrapper);
        } else {
            count = this.baseMapper.updateById(entity);
        }
        return count;
    }

    /**
     * 更新对象实例
     *
     * @param entity                 要更新的数据实体，类型为泛型 T
     * @param updateWrapperGenerator 一个函数，接受一个数据实体，返回一个对该实体进行更新操作的包装器。这个包装器用于
     *                               包装更新操作的逻辑。
     */
    @Override
    public boolean updateById(ID id, T entity, Function<T, Wrapper<T>> updateWrapperGenerator) {
        AssertUtils.notEmpty(id, "id is null.");
        AssertUtils.notNull(entity, "entity is null.");

        BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(entity);
        bw.setPropertyValue(TableInfoUtils.parsePKTableColumn(getEntityClass()).getPropertyName(), id);

        int count = 0;
        if (updateWrapperGenerator != null) {
            count = this.baseMapper.update(entity, updateWrapperGenerator.apply(entity));
        } else {
            count = this.baseMapper.updateById(entity);
        }
        if (count < 1) {
            return false;
        }
        AssertUtils.isTrue(count == 1,
                "update count should == 1.but actual is :{}",
                new Object[]{count});
        return true;
    }

    /**
     * 更新对象实例
     *
     * @param entity                 要更新的数据实体，类型为泛型 T
     * @param updateWrapperGenerator 一个函数，接受一个数据实体，返回一个对该实体进行更新操作的包装器。这个包装器用于
     *                               包装更新操作的逻辑。
     */
    @Override
    public int update(T entity, Function<T, Wrapper<T>> updateWrapperGenerator) {
        AssertUtils.notNull(entity, "entity is null.");

        int count = 0;
        if (updateWrapperGenerator != null) {
            count = this.baseMapper.update(entity, updateWrapperGenerator.apply(entity));
        } else {
            count = this.baseMapper.updateById(entity);
        }
        return count;
    }

    /**
     * 批量更新对象实例
     *
     * @param entityList       要更新的数据实体列表。
     * @param batchSize        批量更新的批次大小。
     * @param useBatchExecutor 是否使用批量执行器。
     */
    @Override
    public void batchUpdate(List<T> entityList, int batchSize, boolean useBatchExecutor) {
        if (CollectionUtils.isEmpty(entityList)) {
            return;
        }
        if (useBatchExecutor) {
            String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);
            executeBatch(entityList, batchSize, (sqlSession, entity) -> {
                MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
                param.put(Constants.ENTITY, entity);
                sqlSession.update(sqlStatement, param);
            });
        } else {
            entityList.stream().forEach(entity -> {
                update(entity);
            });
        }
    }

    /**
     * 批量更新对象实例
     *
     * @param entityList             要更新的数据实体列表。
     * @param updateWrapperGenerator 更新条件生成器。
     * @param batchSize              批量更新的批次大小。
     * @param useBatchExecutor       是否使用批量执行器。
     */
    @Override
    public void batchUpdate(List<T> entityList, Function<T, Wrapper<T>> updateWrapperGenerator, int batchSize,
                            boolean useBatchExecutor) {
        if (CollectionUtils.isEmpty(entityList)) {
            return;
        }
        if (useBatchExecutor) {
            String sqlStatement = getSqlStatement(SqlMethod.UPDATE);
            executeBatch(entityList, batchSize, (sqlSession, entity) -> {
                Map<String, Object> param = new HashMap<>();
                param.put(Constants.WRAPPER, updateWrapperGenerator.apply(entity));
                sqlSession.update(sqlStatement, param);
            });
        } else {
            entityList.stream().forEach(entity -> {
                update(entity);
            });
        }
    }

    /**
     * 根据主键查询对象实例
     *
     * @param pk 主键
     */
    @Override
    public T findById(ID pk) {
        return this.baseMapper.findById(pk);
    }

    /**
     * 根据主键查询对象实例
     *
     * @param entity 实体对象
     */
    @Override
    public T find(T entity) {
        QuerierWrapper<T> wrapper = QuerierWrapper.<T>builder().build();
        wrapper.setEntity(entity);
        return this.baseMapper.find(wrapper);
    }

    /**
     * 查询分页列表
     *
     * @param params    查询参数
     * @param pageIndex 页码
     * @param pageSize  页大小
     * @return 符合条件的记录列表
     */
    @Override
    public PagedList<T> queryPagedList(Map<String, Object> params, int pageIndex, int pageSize) {
        return this.baseMapper.queryPagedList(postQueryMapToWrapper().apply(params), pageIndex, pageSize);
    }

    /**
     * 查询分页列表
     *
     * @param wrapper   查询条件
     * @param params    查询参数
     * @param pageIndex 页码
     * @param pageSize  页大小
     * @return 符合条件的记录列表
     */
    @Override
    public PagedList<T> queryPagedList(Wrapper<T> wrapper, Map<String, Object> params, int pageIndex, int pageSize) {
        AbstractWrapper aw = (AbstractWrapper) postQueryMapToWrapper((AbstractWrapper) wrapper).apply(params);
        return this.baseMapper.queryPagedList(aw, pageIndex, pageSize);
    }

    /**
     * 查询分页列表
     *
     * @param params    查询参数
     * @param pageIndex 页码
     * @param pageSize  页大小
     * @param count     总记录数
     * @return 符合条件的记录列表
     */
    @Override
    public PagedList<T> queryPagedList(Map<String, Object> params, int pageIndex, int pageSize, int count) {
        return this.baseMapper.queryPagedList(postQueryMapToWrapper().apply(params), pageIndex, pageSize, count);
    }

    /**
     * 查询分页列表
     *
     * @param wrapper   查询条件
     * @param params    查询参数
     * @param pageIndex 页码
     * @param pageSize  页大小
     * @param count     总记录数
     * @return 符合条件的记录列表
     */
    @Override
    public PagedList<T> queryPagedList(Wrapper<T> wrapper, Map<String, Object> params, int pageIndex, int pageSize,
                                       int count) {
        AbstractWrapper aw = (AbstractWrapper) postQueryMapToWrapper((AbstractWrapper) wrapper).apply(params);
        return this.baseMapper.queryPagedList(aw, pageIndex, pageSize, count);
    }

    /**
     * 查询列表
     *
     * @param params 查询参数
     * @return 符合条件的记录列表
     */
    @Override
    public List<T> queryList(Map<String, Object> params) {
        return this.baseMapper.queryList(postQueryMapToWrapper().apply(params));
    }

    /**
     * 查询列表
     *
     * @param wrapper 查询条件
     * @param params  查询参数
     * @return 符合条件的记录列表
     */
    @Override
    public List<T> queryList(Wrapper<T> wrapper, Map<String, Object> params) {
        AbstractWrapper aw = (AbstractWrapper) postQueryMapToWrapper((AbstractWrapper) wrapper).apply(params);
        return this.baseMapper.queryList(aw);
    }

    /**
     * 统计符合条件的记录数
     *
     * @param params  查询参数
     * @param exclude 排除的记录ID
     * @return 符合条件的记录数
     */
    @Override
    public int count(Map<String, Object> params, ID exclude) {
        String pkColumnName = TableInfoUtils.parsePKTableColumn(getEntityClass()).getColumnName();
        AbstractWrapper aw = (AbstractWrapper) postQueryMapToWrapper().apply(params);
        if (ObjectUtil.isNotEmpty(exclude)) {
            aw.ne(pkColumnName, exclude);
        }
        return this.baseMapper.count(aw).intValue();
    }

    /**
     * 统计符合条件的记录数
     *
     * @param wrapper 查询条件
     * @param params  查询参数
     * @param exclude 排除的记录ID
     * @return 符合条件的记录数
     */
    @Override
    public int count(Wrapper<T> wrapper, Map<String, Object> params, ID exclude) {
        String pkColumnName = TableInfoUtils.parsePKTableColumn(getEntityClass()).getColumnName();
        AbstractWrapper aw = (AbstractWrapper) postQueryMapToWrapper((AbstractWrapper) wrapper).apply(params);
        if (ObjectUtil.isNotEmpty(exclude)) {
            aw.ne(pkColumnName, exclude);
        }
        return this.baseMapper.count(aw).intValue();
    }

    /**
     * 批量执行操作
     *
     * @param list      需要进行批量操作的数据集合
     * @param batchSize 每次批量操作的大小
     * @param consumer  消费者接口，定义了如何处理每个数据项
     * @param <E>       数据集合中元素的类型
     * @return 执行结果，成功返回true，失败返回false
     */
    protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
        // 通过SqlHelper工具类执行批量操作，传入SqlSessionFactory、日志对象、数据集合、批量大小及操作定义
        return SqlHelper.executeBatch(getSqlSessionFactory(), this.log, list, batchSize, consumer);
    }

    /**
     * 批量执行操作
     *
     * @param list     需要进行批量操作的数据集合
     * @param consumer 消费者接口，定义了如何处理每个数据项
     * @param <E>      数据集合中元素的类型
     * @return 执行结果，成功返回true，失败返回false
     */
    protected <E> boolean executeBatch(Collection<E> list, BiConsumer<SqlSession, E> consumer) {
        return executeBatch(list, getDefaultBatchSize(), consumer);
    }

    /**
     * 根据指定的SqlMethod获取相应的SqlStatement。
     * 这个方法通过传递一个SqlMethod枚举值来查询与之对应的SQL语句。
     * 查询过程委托给了SqlHelper的getSqlStatement方法，该方法会根据传入的mapper类和SqlMethod来构建并返回相应的SQL语句。
     *
     * @param sqlMethod 表示SQL方法的枚举值，用于指定需要获取的SQL语句的类型。
     * @return 返回根据指定SqlMethod匹配的SqlStatement字符串。
     */
    protected String getSqlStatement(SqlMethod sqlMethod) {
        // 委托给SqlHelper的getSqlStatement方法获取SQL语句
        return SqlHelper.getSqlStatement(mapperClass, sqlMethod);
    }


    protected Class<T> currentModelClass() {
        return (Class<T>) this.typeArguments[0];
    }

    protected Class<M> currentMapperClass() {
        return (Class<M>) this.typeArguments[2];
    }


    /**
     * 获取SqlSessionFactory
     * 实现参考Mybatis-plus中ServiceImpl的实现
     *
     * @return
     */
    @SuppressWarnings({"rawtypes", "deprecation"})
    protected SqlSessionFactory getSqlSessionFactory() {
        if (this.sqlSessionFactory == null) {
            synchronized (this) {
                if (this.sqlSessionFactory == null) {
                    Object target = this.baseMapper;
                    // 这个检查目前看着来说基本上可以不用判断Aop是不是存在了.
                    if (com.baomidou.mybatisplus.extension.toolkit.AopUtils.isLoadSpringAop()) {
                        if (AopUtils.isAopProxy(this.baseMapper)) {
                            target = AopProxyUtils.getSingletonTarget(this.baseMapper);
                        }
                    }
                    if (target != null) {
                        MybatisMapperProxy mybatisMapperProxy = (MybatisMapperProxy) Proxy.getInvocationHandler(target);
                        SqlSessionTemplate sqlSessionTemplate = (SqlSessionTemplate) mybatisMapperProxy.getSqlSession();
                        this.sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();
                    } else {
                        this.sqlSessionFactory = GlobalConfigUtils.currentSessionFactory(this.entityClass);
                    }
                }
            }
        }
        return this.sqlSessionFactory;
    }

    /**
     * 获取当前实例对应的实体类型
     * <br/>
     * 该方法不需要参数，调用后会返回一个Class<T>类型的对象，这个对象代表了当前实例所对应的实体类型。
     *
     * @return 返回代表实体类型的Class对象
     */
    @Override
    public Class<T> getEntityClass() {
        return this.entityClass; // 返回实例化的实体类型类
    }

    /**
     * 获取基础映射器接口的实例。这个方法用于返回一个持久层实现的接口，以便于在其它部分的代码中使用。
     *
     * @return M类型的实例，代表了持久层的一个具体实现。
     */
    public M getBaseMapper() {
        return this.baseMapper; // 返回当前类中定义的持久层映射器实例
    }


    /**
     * postQuery
     *
     * @return
     */
    protected Function<Map<String, Object>, Wrapper<T>> postUpdateMapToWrapper() {
        return new Function<Map<String, Object>, Wrapper<T>>() {
            @Override
            public Wrapper<T> apply(Map<String, Object> params) {
                if (params == null) {
                    return null;
                }
                Map<String, TableInfoUtils.TableColumnInfo> p2cMap =
                        TableInfoUtils.parseTableColumnMap(getEntityClass());
                TableInfoUtils.TableColumnInfo pkColumnInfo = TableInfoUtils.parsePKTableColumn(getEntityClass());
                UpdaterWrapper<T> qw = UpdaterWrapper.<T>builder().build();
                for (Map.Entry<String, Object> entryTemp : params.entrySet()) {
                    if (p2cMap.containsKey(entryTemp.getKey())) {
                        if (StrUtil.equals(pkColumnInfo.getPropertyName(), entryTemp.getKey())) {
                            qw.eq(p2cMap.get(entryTemp.getKey()).getColumnName(), entryTemp.getValue());
                        } else {
                            qw.set(p2cMap.get(entryTemp.getKey()).getColumnName(), entryTemp.getValue());
                        }

                    } else {
                        qw.set(entryTemp.getKey(), entryTemp.getValue());
                    }
                }
                return qw;
            }
        };
    }

    /**
     * postQuery
     *
     * @return
     */
    protected Function<Map<String, Object>, Wrapper<T>> postQueryMapToWrapper() {
        return postQueryMapToWrapper(null);
    }

    /**
     * postQuery
     *
     * @return
     */
    protected Function<Map<String, Object>, Wrapper<T>> postQueryMapToWrapper(AbstractWrapper wrapper) {
        return new Function<Map<String, Object>, Wrapper<T>>() {
            @Override
            public Wrapper<T> apply(Map<String, Object> params) {
                if (MapUtils.isEmpty(params)) {
                    return wrapper;
                }
                Map<String, TableInfoUtils.TableColumnInfo> p2cMap =
                        TableInfoUtils.parseTableColumnMap(getEntityClass());
                AbstractWrapper nw = wrapper == null ? QuerierWrapper.<T>builder().build() : wrapper;

                for (Map.Entry<String, Object> entryTemp : params.entrySet()) {
                    if (p2cMap.containsKey(entryTemp.getKey())) {
                        nw.eq(p2cMap.get(entryTemp.getKey()).getColumnName(), entryTemp.getValue());
                    } else {
                        nw.eq(entryTemp.getKey(), entryTemp.getValue());
                    }

                }
                return nw;
            }
        };
    }
}
